#include "DxInput.h"
#include "Trace.h"


//DxInput::DxInput()
//{
//	_di = NULL;
//	_Keyboard = NULL;
//}


void DxInput::_InitDirectInput(HINSTANCE hInstance, HWND hWnd)
{
	_hInstance = hInstance;
	_hWnd = hWnd;

	HRESULT
		hr = DirectInput8Create
		(
		_hInstance,//GetModuleHandle(NULL),//_hInstance, 
		DIRECTINPUT_VERSION,
		IID_IDirectInput8, (VOID**)&_di, NULL
		);

	// TO-DO: put in exception handling
	if (hr != DI_OK) return;
	trace(L"DirectInput has been created");

	//initialize keyboard
	hr = _di->CreateDevice(GUID_SysKeyboard, &_Keyboard, NULL);
	// TO-DO: put in exception handling
	if (hr != DI_OK) return;
	trace(L"DirectInput keyboard has been created");

	hr = _Keyboard->SetDataFormat(&c_dfDIKeyboard);
	trace(L"SetDataFormat for keyboard successfully");

	hr = _Keyboard->SetCooperativeLevel(_hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	trace(L"SetCooperativeLevel for keyboard successfully");

	// IMPORTANT STEP TO USE BUFFERED DEVICE DATA!
	//
	// DirectInput uses unbuffered I/O (buffer size = 0) by default.
	// If you want to read buffered data, you need to set a nonzero
	// buffer size.
	//
	// Set the buffer size to DINPUT_BUFFERSIZE (defined above) elements.
	//
	// The buffer size is a DWORD property associated with the device.
	DIPROPDWORD dipdw;

	dipdw.diph.dwSize = sizeof(DIPROPDWORD);
	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj = 0;
	dipdw.diph.dwHow = DIPH_DEVICE;
	dipdw.dwData = KEYBOARD_BUFFER_SIZE; // Arbitary buffer size

	trace(L"SetProperty for keyboard successfully");

	hr = _Keyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
	if (hr != DI_OK) return;

	hr = _Keyboard->Acquire();
	if (hr != DI_OK) return;

	trace(L"Keyboard has been acquired successfully-----------------");

	_Key_Down = 0;
	_Key_Up = 0;

	//moi them vao
	for (int i = 0; i < 256; i++)
	{
		_KeyStatesPress[i] = 0;
	}


	// Retrieve a pointer to an IDirectInputDevice8 interface 
	hr = _di->CreateDevice(GUID_SysMouse, &_Mouse, NULL);

	hr = _Mouse->SetDataFormat(&c_dfDIMouse);

	/*if FAILED(hr) {
	return false;
	} */

	// Set the cooperative level 
	hr = _Mouse->SetCooperativeLevel(_hWnd,
		DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	/*if FAILED(hr)
	{
	return false;
	} */

	// Get access to the input device. 
	hr = _Mouse->Acquire();
	/*while(FAILED(hr))
	_Mouse->Acquire();
	if FAILED(hr)
	{
	return false;
	}
	*/
	_xMouse = 100;
	_yMouse = 100;
	position.x = 720 / 2;
	position.y = 540 / 2;
}

void DxInput::_Process_KeyBoard()
{
	// Collect all key states first
	_Keyboard->GetDeviceState(sizeof(_KeyStates), _KeyStates);

	//if(!SUCCEEDED(dikeyboard->GetDeviceState(sizeof(keys), (LPVOID)&keys)))
	if (!SUCCEEDED(_Keyboard->GetDeviceState(sizeof(_KeyStates), _KeyStates)))
		_Keyboard->Acquire();

	// Collect all buffered events
	DWORD dwElements = KEYBOARD_BUFFER_SIZE;
	HRESULT hr = _Keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), _KeyEvents, &dwElements, 0);

	// Scan through all data, check if the key is pressed or released
	for (DWORD i = 0; i < dwElements; i++)
	{
		int KeyCode = _KeyEvents[i].dwOfs;
		int KeyState = _KeyEvents[i].dwData;
		if ((KeyState & 0x80) > 0)
			_Key_Down = KeyCode;//OnKeyDown(KeyCode);
		else
			_Key_Up = KeyCode;//OnKeyUp(KeyCode);
	}
}

int DxInput::IsKeyDown(int KeyCode)
{
	if (_KeyStates[KeyCode] & 0x80)
	{
		return 1;
	}
	else
	{
		return 0;
	}
	//return (_KeyStates[KeyCode] & 0x80) > 0;
}

int DxInput::IsKeyUp(int KeyCode)
{
	if (_KeyStates[KeyCode] & 0x80)
	{
		return 0;
	}
	else
	{
		return 1;
	}

}

int DxInput::IsKeyPress(int KeyCode)
{
	if (IsKeyDown(KeyCode))
	{
		_KeyStatesPress[KeyCode] = 1;
	}
	if (_KeyStatesPress[KeyCode] == 1)
	{
		if (IsKeyUp(KeyCode))
		{
			_KeyStatesPress[KeyCode] = 2;
		}
	}

	if (_KeyStatesPress[KeyCode] == 2)
	{
		_KeyStatesPress[KeyCode] = 0;
		return 1;
	}

	return 0;

}

int DxInput::GetKeyDown()
{

	//return _Key_Down;

	int temp = _Key_Down;
	_Key_Down = 0;
	return temp;

}
int DxInput::GetKeyUp()
{
	int temp = _Key_Up;
	_Key_Up = 0;
	return temp;
}



void DxInput::_KillDirectInput()
{
	if (_Keyboard)
	{
		_Keyboard->Unacquire();
		_Keyboard->Release();
	}
	if (_Mouse)
	{
		_Mouse->Unacquire();
		_Mouse->Release();
	}
	if (_di) _di->Release();
}



void DxInput::_GetMouse()
{

	_Mouse->Poll();
	if (!SUCCEEDED(_Mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&_mouseState)))
	{
		_Mouse->Acquire();
		_Mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&_mouseState);
	}
	//get mouse position on screen
	GetCursorPos(&position);
	ScreenToClient(_hWnd, &position);
	RECT r;
	GetClientRect(_hWnd, &r);
	position.x = (position.x * 800) / 794;
	position.y = (position.y * 600) / 572;
}


